package models

import (
	"context"
	"strings"
	"time"
	"wx-uniapp-go/third_party/aeslib"
	"wx-uniapp-go/utils"
)

const (
	DpUserGroupTemplateManager = "tm"
	DpUserGroupUser            = "user"
)

const (
	DpUserVipGroupIdFree = 10 // 普通用户
)

type User struct {
	Id            int64      `json:"id" xorm:"not null pk autoincr comment('用户ID') INT(11)"`
	UniqueId      string     `json:"unique_id" xorm:"not null default '' comment('用户unique_id') unique VARCHAR(50)"`
	UnionId       string     `json:"union_id" xorm:"not null default '' comment('微信union_id') VARCHAR(100)"`
	OpenId        string     `json:"open_id" xorm:"not null default '' comment('微信open_id') VARCHAR(100)"`
	Avatar        string     `json:"avatar" xorm:"not null default '' comment('头像') VARCHAR(255)"`
	Mobile        string     `json:"mobile" xorm:"not null default '' comment('手机号') unique VARCHAR(32)"`
	Nickname      string     `json:"nickname" xorm:"not null default '' comment('昵称') VARCHAR(100)"`
	Password      string     `json:"password" xorm:"not null default '' comment('密码hash') VARCHAR(150)"`
	Salt          string     `json:"salt" xorm:"not null default '' comment('密码盐') VARCHAR(200)"`
	Status        int        `json:"status" xorm:"not null default 'normal' comment('用户状态locked,normal') VARCHAR(20)"`
	RegTime       time.Time  `json:"reg_time" xorm:"not null default 'CURRENT_TIMESTAMP' comment('注册时间') DATETIME"`
	RegFrom       string     `json:"reg_from" xorm:"not null default '' comment('注册来源应用ID') VARCHAR(20)"`
	RegIp         string     `json:"reg_ip" xorm:"not null default '' comment('注册IP') VARCHAR(30)"`
	UpdateTime    time.Time  `json:"update_time" xorm:"not null default 'CURRENT_TIMESTAMP' comment('更新时间') DATETIME"`
	LastLoginTime time.Time  `json:"last_login_time" xorm:"not null default 'CURRENT_TIMESTAMP' comment('注册时间') DATETIME"`
	LastLoginIp   string     `json:"last_login_ip" xorm:"not null default '' comment('最后登录IP') VARCHAR(30)"`
	VisitTime     *time.Time `json:"visit_time" xorm:"not null default 'CURRENT_TIMESTAMP' comment('访问时间') DATETIME"`
	Group         string     `json:"group" xorm:"not null default '' comment('用户类型：user用户 tm(template_manager)管理员') VARCHAR(20)"`
	InviteCode    string     `json:"invite_code" xorm:"not null comment('邀请码') VARCHAR(50)"`
	Duration      int64      `json:"duration" xorm:"not null comment('剩余时长 秒单位') INT(11)"`
	NewUser       int        `json:"new_user" xorm:"not null comment('是否是新用户 0 是 1不是') TINYINT"`
	InviteUser    int64      `json:"invite_user" xorm:"default 0  comment('受邀用户id') INT(11)"`
	Balance       float64    `json:"balance"`
	LogOffTime    *time.Time `json:"log_off_time" xorm:"null comment('注销时间') DATETIME"`
}

// LastMobile 获取手机尾号4位数
func (d *User) LastMobile() string {
	i := len(d.Mobile) - 4
	if i <= 0 {
		i = 0
	}
	return d.Mobile[i:]
}

func DpUserGetListsByPage(ctx context.Context, page, pageSize int, fields []string, quary any, args ...any) (data []*User, count int64, err error) {
	data = make([]*User, 0)
	session := getSession(ctx)
	if len(fields) > 0 {
		session = session.Select(strings.Join(fields, ","))
	}
	count, err = session.Where(quary, args...).Desc("create_time").
		Limit(pageSize, (page-1)*pageSize).FindAndCount(&data)
	return
}

func UserGetOneById(ctx context.Context, id int64, cols ...string) (data *User, err error) {
	data = new(User)
	db := getSession(ctx).ID(id)
	if len(cols) > 0 {
		db = db.Cols(cols...)
	}
	_, err = db.Get(data)
	return
}

func UserFindByIds(ctx context.Context, ids []int64) (data []*User, err error) {
	err = getSession(ctx).In("id", ids).Find(&data)
	return
}

func UserGetOneByCode(ctx context.Context, code string) (data *User, err error) {
	data = new(User)
	_, err = getSession(ctx).Where("invite_code = ?", code).Get(data)
	return
}

func GetUserByOpenId(ctx context.Context, openId string) (data *User, err error) {
	data = new(User)
	_, err = getSession(ctx).Where("open_id = ?", openId).Get(data)
	return
}

func UidEncode(uid int64) string {
	uidStr := utils.ParseStringInt64(uid)

	s, err := aeslib.AesHexEncrypt(uidStr)
	if err != nil {
		return ""
	}
	return s
}

func UidDecode(uidCode string) int64 {
	uidStr, err := aeslib.AesHexDecrypt(uidCode)
	if err != nil {
		return 0
	}
	return utils.ParseInt64String(uidStr)
}
